package com.three.mahjong.base.service;

import com.three.exception.GameException;
import com.three.mahjong.base.model.Card;
import com.three.mahjong.base.model.MJPlayer;
import com.three.mahjong.base.model.MJTable;
import com.three.mahjong.base.rule.MJBaseRule;
import com.three.protocol.MJModule;
import com.three.protocol.MJModule.OperateInfo;
import com.three.protocol.MJModule.OptionsType;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by panzhitian on 2017/7/16.
 */
public class MJBaseService {

    private MJBaseRule mjBaseRule;

    private int gameType;

    @Autowired
    private MJFriendRoomManager mjFriendRoomManager;

    /**
     * 处理出牌
     * @param pais
     */
    public void dealPaiOut(List<Integer> pais, MJTable table) {
        List<Card> cards = mjBaseRule.changeToCardList(pais);
        //设置最近出牌
        table.setLastOutPai(pais.get(0));


    }

    public void dealGang() {

    }

    public void dealPeng() {

    }

    /**
     * 初始化牌桌
     * @return
     */
    public List<Integer> initTable() {
        return mjBaseRule.initTableCard(gameType);
    }


//    public void dealGang()

    /**
     * 获取玩家操作之后的返回信息
     * @param playerId
     * @param operateInfo
     */
    public void getOperateResultResp(long playerId, OperateInfo operateInfo) {
        //根据玩家id获取牌局对象
        MJTable mjTable = mjFriendRoomManager.getTableByPlayerId(playerId);
        //根据玩家id获取玩家对象
        MJPlayer mjPlayer = mjTable.getPlayerByPlayerId(playerId);

        dealPlayersOperate(mjTable,mjPlayer,operateInfo);
    }

    /**
     * 处理多个玩家同时操作的情况
     * @param mjTable
     * @param mjPlayer
     * @param operateInfo
     */
    public void dealPlayersOperate(MJTable mjTable, MJPlayer mjPlayer, OperateInfo operateInfo) {
        // 获取玩家的可操作列表
        ConcurrentHashMap<Integer, List<OptionsType>> canOperateMap = mjTable.getCanOperateMap();
        // 获取玩家点了的操作
        ConcurrentHashMap<Integer, OptionsType> operateMap = mjTable.getOperateMap();

        // 获取玩家操作
        OptionsType optionsType = operateInfo.getType();

        operateMap.put(mjPlayer.getSeat(), optionsType);

        int seat = getTrulyOperate(canOperateMap, operateMap, mjTable);

        if (seat == 0 || canOperateMap.contains(seat)) {// 没有玩家执行操作或者优先级最高的操作还没有点击过来
            return;
        }
        // 获取最终需要执行的操作
        OptionsType optionsType2 = operateMap.get(seat);

        OperateInfo.Builder operateInfoBuilder = OperateInfo.newBuilder();
        operateInfoBuilder.setType(optionsType2);
        operateInfoBuilder.addAllPai(operateInfo.getPaiList());
        dealOperate(mjTable, mjPlayer, operateInfoBuilder.build());

    }

    /**
     * 实际处理操作
     * @param mjPlayer
     * @param mjPlayer
     * @param operateInfo
     */
    public void dealOperate(MJTable mjTable,MJPlayer mjPlayer,OperateInfo operateInfo){
        // 玩家当前操作
        OptionsType optionsType = operateInfo.getType();

        switch (optionsType.getNumber()) {
            case OptionsType.PENG_VALUE:// 碰
                mjBaseRule.dealPeng(mjPlayer,mjTable);
                break;
            default:
                break;
        }
    }

    /**
     * 根据优先级获取真正能执行的操作的座位
     *
     * @param operateMap
     * @return
     */
    public int getTrulyOperate(ConcurrentHashMap<Integer, List<OptionsType>> canOperateMap,
                               ConcurrentHashMap<Integer, OptionsType> operateMap, MJTable mjTable) {

        // 获取上一个打牌玩家座位
        int lastSeat = mjTable.getLastSeat();

        int seat = 0;
        if (operateMap.size() == canOperateMap.size()) {// 全部已经接收到了所有能点击

            if (operateMap.size() == 0) {
                //throw new GameException();
            } else if (operateMap.size() == 1) {// 当前只有一个能点击操作
                for (int seat1 : operateMap.keySet()) {
                    return seat1;
                }
            } else {// 当前有多个玩家点击操作
                //根据优先级选择操作
                //TODO
            }

        }

        return seat;
    }
}
